"""
工作流管理 API 路由
"""
import json
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from typing import Optional

from database import get_db
from schemas.workflow_schema import (
    WorkflowCreate,
    WorkflowUpdate,
    WorkflowResponse,
    WorkflowDetailResponse,
    WorkflowListResponse,
    WorkflowRunRequest,
    WorkflowRunResponse,
    WorkflowInstanceResponse,
    WorkflowInstanceDetailResponse,
    WorkflowInstanceListResponse,
    RetryRequest,
    WorkflowLogsResponse,
    WorkflowLogResponse,
    NodeExecutionInfo
)
from services.workflow_service import WorkflowService
from services.workflow_engine import WorkflowEngine

router = APIRouter(prefix="/api/workflows", tags=["工作流管理"])


# ============ 工作流 CRUD 接口 ============

@router.post("", response_model=WorkflowDetailResponse, summary="创建工作流")
def create_workflow(
    workflow_create: WorkflowCreate,
    db: Session = Depends(get_db)
):
    """
    创建工作流

    - **name**: 工作流名称(必填)
    - **description**: 工作流描述(可选)
    - **workflow_definition**: 工作流定义(必填)
    - **cron_expression**: Cron 表达式(可选)
    - **cron_enabled**: 是否启用定时调度(默认 false)
    """
    success, error_msg, workflow = WorkflowService.create_workflow(db, workflow_create)

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    # 如果启用了定时调度，添加定时任务
    if workflow.cron_enabled and workflow.cron_expression:
        from services.scheduler_service import scheduler_service
        scheduler_service.add_workflow_job(workflow.id, workflow.cron_expression)

    return WorkflowDetailResponse(
        id=workflow.id,
        name=workflow.name,
        description=workflow.description,
        workflow_definition=json.loads(workflow.workflow_definition),
        cron_expression=workflow.cron_expression,
        cron_enabled=workflow.cron_enabled,
        status=workflow.status,
        created_at=workflow.created_at,
        updated_at=workflow.updated_at,
        created_by=workflow.created_by
    )


@router.get("", response_model=WorkflowListResponse, summary="查询工作流列表")
def get_workflow_list(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    name: Optional[str] = Query(None, description="工作流名称(模糊查询)"),
    status: Optional[str] = Query(None, description="工作流状态"),
    sort_by: str = Query("created_at", description="排序字段(name/created_at/updated_at)"),
    order: str = Query("desc", description="排序方向(asc/desc)"),
    db: Session = Depends(get_db)
):
    """
    查询工作流列表

    支持分页、筛选、排序
    """
    total, workflows = WorkflowService.list_workflows(
        db, page, page_size, name, status, sort_by, order
    )

    items = [
        WorkflowResponse(
            id=w.id,
            name=w.name,
            description=w.description,
            status=w.status,
            created_at=w.created_at,
            updated_at=w.updated_at
        )
        for w in workflows
    ]

    return WorkflowListResponse(
        total=total,
        page=page,
        page_size=page_size,
        items=items
    )


@router.get("/{workflow_id}", response_model=WorkflowDetailResponse, summary="查询工作流详情")
def get_workflow_detail(
    workflow_id: int,
    db: Session = Depends(get_db)
):
    """
    查询工作流详情
    """
    workflow = WorkflowService.get_workflow(db, workflow_id)

    if not workflow:
        raise HTTPException(status_code=404, detail="工作流不存在")

    return WorkflowDetailResponse(
        id=workflow.id,
        name=workflow.name,
        description=workflow.description,
        workflow_definition=json.loads(workflow.workflow_definition),
        cron_expression=workflow.cron_expression,
        cron_enabled=workflow.cron_enabled,
        status=workflow.status,
        created_at=workflow.created_at,
        updated_at=workflow.updated_at,
        created_by=workflow.created_by
    )


@router.put("/{workflow_id}", response_model=WorkflowDetailResponse, summary="更新工作流")
def update_workflow(
    workflow_id: int,
    workflow_update: WorkflowUpdate,
    db: Session = Depends(get_db)
):
    """
    更新工作流
    """
    success, error_msg, workflow = WorkflowService.update_workflow(
        db, workflow_id, workflow_update
    )

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    # 管理定时任务
    from services.scheduler_service import scheduler_service
    if workflow.cron_enabled and workflow.cron_expression:
        # 启用定时调度，添加或更新任务
        scheduler_service.add_workflow_job(workflow.id, workflow.cron_expression)
    else:
        # 禁用定时调度，删除任务
        scheduler_service.remove_workflow_job(workflow.id)

    return WorkflowDetailResponse(
        id=workflow.id,
        name=workflow.name,
        description=workflow.description,
        workflow_definition=json.loads(workflow.workflow_definition),
        cron_expression=workflow.cron_expression,
        cron_enabled=workflow.cron_enabled,
        status=workflow.status,
        created_at=workflow.created_at,
        updated_at=workflow.updated_at,
        created_by=workflow.created_by
    )


@router.delete("/{workflow_id}", summary="删除工作流")
def delete_workflow(
    workflow_id: int,
    db: Session = Depends(get_db)
):
    """
    删除工作流(软删除)
    """
    success, error_msg = WorkflowService.delete_workflow(db, workflow_id)

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    return {"message": "工作流删除成功"}


# ============ 工作流执行接口 ============

@router.post("/{workflow_id}/run", response_model=WorkflowRunResponse, summary="运行工作流")
def run_workflow(
    workflow_id: int,
    run_request: WorkflowRunRequest,
    db: Session = Depends(get_db)
):
    """
    运行工作流

    - **input_params**: 输入参数(可选)
    """
    workflow = WorkflowService.get_workflow(db, workflow_id)

    if not workflow:
        raise HTTPException(status_code=404, detail="工作流不存在")

    engine = WorkflowEngine(db)
    success, error_msg, instance = engine.start_workflow(
        workflow_id=workflow_id,
        instance_name=f"{workflow.name}-{int(datetime.now().timestamp())}",
        trigger_type="manual",
        input_params=run_request.input_params
    )

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    return WorkflowRunResponse(
        instance_id=instance.id,
        status=instance.status
    )


# ============ 工作流实例接口 ============

@router.get("/instances/list", response_model=WorkflowInstanceListResponse, summary="查询工作流实例列表")
def get_workflow_instance_list(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    workflow_id: Optional[int] = Query(None, description="工作流ID"),
    status: Optional[str] = Query(None, description="实例状态"),
    include_not_started: bool = Query(False, description="是否包含未运行状态的实例"),
    db: Session = Depends(get_db)
):
    """
    查询工作流实例列表

    支持分页、按工作流ID和状态筛选
    include_not_started: 是否包含"未运行"状态的实例（默认False）
    """
    total, instances = WorkflowService.list_workflow_instances(
        db, page, page_size, workflow_id, status, include_not_started
    )

    items = [
        WorkflowInstanceResponse(
            id=i.id,
            workflow_id=i.workflow_id,
            instance_name=i.instance_name,
            status=i.status,
            trigger_type=i.trigger_type,
            schedule_type=i.schedule_type if hasattr(i, 'schedule_type') else 'manual',
            schedule_config=json.loads(i.schedule_config) if i.schedule_config else None,
            created_at=i.created_at,
            started_at=i.started_at,
            finished_at=i.finished_at,
            duration=i.duration
        )
        for i in instances
    ]

    return WorkflowInstanceListResponse(
        total=total,
        page=page,
        page_size=page_size,
        items=items
    )


@router.get("/instances/{instance_id}", response_model=WorkflowInstanceDetailResponse, summary="查询工作流实例详情")
def get_workflow_instance_detail(
    instance_id: int,
    db: Session = Depends(get_db)
):
    """
    查询工作流实例详情
    """
    instance = WorkflowService.get_workflow_instance(db, instance_id)

    if not instance:
        raise HTTPException(status_code=404, detail="工作流实例不存在")

    # 获取节点执行记录
    node_executions = WorkflowService.get_node_executions(db, instance_id)

    nodes_execution = [
        NodeExecutionInfo(
            node_id=ne.node_id,
            node_name=ne.node_name,
            node_type=ne.node_type,
            status=ne.status,
            started_at=ne.started_at,
            finished_at=ne.finished_at,
            output_data=json.loads(ne.output_data) if ne.output_data else None,
            error_message=ne.error_message
        )
        for ne in node_executions
    ]

    return WorkflowInstanceDetailResponse(
        id=instance.id,
        workflow_id=instance.workflow_id,
        template_id=instance.template_id,
        template_version=instance.template_version,
        template_name=instance.template_name,
        instance_name=instance.instance_name,
        status=instance.status,
        workflow_definition_snapshot=instance.workflow_definition_snapshot,
        current_node_id=instance.current_node_id,
        trigger_type=instance.trigger_type,
        trygger_user=instance.trigger_user,
        schedule_type=instance.schedule_type if hasattr(instance, 'schedule_type') else 'manual',
        schedule_config=json.loads(instance.schedule_config) if instance.schedule_config else None,
        input_params=json.loads(instance.input_params) if instance.input_params else None,
        nodes_execution=nodes_execution,
        created_at=instance.created_at,
        created_by=instance.created_by,
        started_at=instance.started_at,
        finished_at=instance.finished_at,
        duration=instance.duration,
        error_message=instance.error_message
    )


@router.post("/instances/{instance_id}/pause", summary="暂停工作流实例")
def pause_workflow_instance(
    instance_id: int,
    db: Session = Depends(get_db)
):
    """
    暂停工作流实例
    """
    engine = WorkflowEngine(db)
    success, error_msg = engine.pause_workflow(instance_id)

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    return {"message": "暂停请求已发送"}


@router.post("/instances/{instance_id}/resume", summary="恢复工作流实例")
def resume_workflow_instance(
    instance_id: int,
    db: Session = Depends(get_db)
):
    """
    恢复工作流实例
    """
    engine = WorkflowEngine(db)
    success, error_msg = engine.resume_workflow(instance_id)

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    return {"message": "工作流已恢复执行"}


@router.post("/instances/{instance_id}/retry", summary="重试工作流实例")
def retry_workflow_instance(
    instance_id: int,
    retry_request: RetryRequest,
    db: Session = Depends(get_db)
):
    """
    重试工作流实例

    - **from_node_id**: 从哪个节点开始重试(可选)
    """
    engine = WorkflowEngine(db)
    success, error_msg = engine.retry_workflow(
        instance_id,
        retry_request.from_node_id
    )

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    return {"message": "工作流已开始重试"}


@router.post("/instances/{instance_id}/cancel", summary="取消工作流实例")
def cancel_workflow_instance(
    instance_id: int,
    db: Session = Depends(get_db)
):
    """
    取消工作流实例
    """
    engine = WorkflowEngine(db)
    success, error_msg = engine.cancel_workflow(instance_id)

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    return {"message": "工作流已取消"}


@router.get("/instances/{instance_id}/logs", response_model=WorkflowLogsResponse, summary="查询工作流实例日志")
def get_workflow_instance_logs(
    instance_id: int,
    node_id: Optional[str] = Query(None, description="节点ID"),
    log_level: Optional[str] = Query(None, description="日志级别"),
    db: Session = Depends(get_db)
):
    """
    查询工作流实例日志

    - **node_id**: 节点ID(可选)
    - **log_level**: 日志级别(可选)
    """
    logs = WorkflowService.get_workflow_logs(db, instance_id, node_id, log_level)

    # 获取节点执行记录,用于获取node_id
    node_executions = WorkflowService.get_node_executions(db, instance_id)
    execution_to_node = {ne.id: ne.node_id for ne in node_executions}

    log_responses = [
        WorkflowLogResponse(
            log_time=log.log_time,
            log_level=log.log_level,
            log_message=log.log_message,
            node_id=execution_to_node.get(log.node_execution_id) if log.node_execution_id else None
        )
        for log in logs
    ]

    return WorkflowLogsResponse(logs=log_responses)


@router.delete("/instances/{instance_id}", summary="删除工作流实例")
def delete_workflow_instance(
    instance_id: int,
    db: Session = Depends(get_db)
):
    """
    删除工作流实例(软删除)

    注意:不允许删除正在运行的实例
    """
    success, error_msg = WorkflowService.delete_workflow_instance(db, instance_id)

    if not success:
        raise HTTPException(status_code=400, detail=error_msg)

    return {"message": "工作流实例删除成功"}
